# -*- coding: utf-8 -*-
"""
Created on Mon Jul 10 14:58:55 2023
@author: leonyang,xucanming
"""
import configparser
import requests
import ping3
import logging
import time,os
def AutoReboot(isAutoReboot):
    if isAutoReboot == "True":
        print("AutoReboot after 10 seconds!")
        print("Press Ctrl+C to stop auto rebooting!")
        time.sleep(10)
        try:
            #os.system("ipmitool -H "login_host" -I lan -U "username" -P "password" power reset") 
            print("reboot ok")  
        except Exception:
            print("reboot failed,Please manually restart!")
    else:
        print("Please manually restart!")
        print("All modifications take effect after restarting the machine!")
def getX_Auth_Token(login_host,username,password):
    X_Auth_Token = None
    cmd = "curl -i -k -X POST \"https://"+login_host+"/redfish/v1/SessionService/Sessions\" -H \"Content-Type:application/json\" --data {\\\"UserName\\\":\\\""+username+"\\\"\\,\\\"Password\\\":\\\""+password+"\\\"}"
    if os.path.exists("baixintmp.txt"):
        os.remove("baixintmp.txt")
    os.system(cmd+ " > baixintmp.txt")
    print()
    with open("baixintmp.txt") as file_handle:
        data = file_handle.readlines()
        for i in data:
            if "400 Bad Request" in i:
                print("Network status:400 Bad Request")
                print("X_Auth_Token: None!")
                logging.info("Network status:400 Bad Request")
                logging.info("X_Auth_Token: None!")
                break
            if "X-Auth-Token" in i:
                X_Auth_Token = i.split(":")[1].strip()
                print("X_Auth_Token:",X_Auth_Token)
                logging.info("X_Auth_Token:",X_Auth_Token)
    return X_Auth_Token
########################################################
class MyConfig():
    
    def __init__(self,filename):
        self.filename=filename
        self.cf = configparser.ConfigParser()
        self.cf.read(filename)
        
    def get(self,section,option):
        value=self.cf.get(section,option)
        return value       
########################################################
print("**********************************************************************************\n")
print("****** Copyright (c) 2023 - 2024, 100Trust Corporation. All rights reserved ******\n")
print("**********************************************************************************\n")
current_time = time.strftime("%Y%m%d_%H%M%S") 
log_file = f'log_{current_time}.txt'
logging.basicConfig(filename=log_file, level=logging.DEBUG)
logging.info("**********************************************************************************")
logging.info("****** Copyright (c) 2023 - 2024, 100Trust Corporation. All rights reserved ******")
logging.info("**********************************************************************************")
if os.geteuid() != 0:
    print ("This program must be run as root. Aborting.")
    logging.error("This program must be run as root. Aborting.")
    exit(-1)
    
#判断unit_info.ini文件是否存在
try:
  f = open('unit_info.ini')
  f.close()
except IOError:
  print('unit_info.ini does not exist. exit.')
  logging.error('unit_info.ini does not exist. exit.')
  exit(1)
#账户&密码固定
username = MyConfig("unit_info.ini").get("name_info","name")
password = MyConfig("unit_info.ini").get("passwd_info","pwd")
#多个IP，根据i获取ip地址，j为总的IP个数，记录fail机台总数，以及pass机台总数      
j = MyConfig("unit_info.ini").get("ip_info","i")
Failed = 0
Passed = 0
i = 1
while int(i) <= int(j):
    try:
        login_host = MyConfig("unit_info.ini").get("ip_info",f'ip{i}')
        print(f'ip{i}' " start...")
        #login_host = f'192.168.1.{i}'
    except Exception:
        print(f'{i} not exist,please check the configuration file IP!')
        logging.info(f'{i} not exist,please check the configuration file IP!')
    #ping ip
    response = ping3.ping(login_host, timeout=3)
    if response:
        #pass执行
        print("ping Pass: " f'{login_host}' " reachable" )
        logging.info(" ping Pass: " f'{login_host}' " reachable")
        print() 
########################################################
#执行Bios变量修改
        #获取X-Auth-Token
        # Authurl = "https://"+login_host+"/redfish/v1/SessionService/Sessions"
        # Auth = requests.get(Authurl,headers={'Content-Type ':'application/json'},auth=(username, password),verify=False)
        # print(Auth.headers)
       # X_Auth_Token = getX_Auth_Token(login_host,username,password)
        X_Auth_Token = None
    
        #MAX_RETRIES = 5 
        #retries = 0 
        #while X_Auth_Token is None and retries < MAX_RETRIES:
        # 重试获取的逻辑
        #     retries += 1
        #     time.sleep(1) 
        #     print("X_Auth_Token is None,get X_Auth_Token retry {retries} cycle!")
        #     logging.error("X_Auth_Token is None,get X_Auth_Token retry {retries} cycle!")
        #     if retries > MAX_RETRIES:
        #        raise Exception("The number of retries exceeded the limit!Skip continuing program execution")
        #        logging.error("The number of retries exceeded the limit!Skip continuing program execution")
        #     X_Auth_Token = getX_Auth_Token(login_host,username,password)
        #print("X_Auth_Token:"+str(X_Auth_Token))
        #logging.debug("X_Auth_Token:"+str(X_Auth_Token))
        
        #获取BIOS settings
        base_url = "https://"+login_host+"/redfish/v1/"
        systems_url = base_url + 'Systems/'
        bios_url =  base_url + 'Systems/1/Bios/'
        
        print("Access:",systems_url)
        logging.debug("Access:",systems_url)
        RedfishSession = requests.session()
        SessionHeaders = RedfishSession.headers
        print("SessionHeaders: ",SessionHeaders)
        logging.debug("SessionHeaders: ",SessionHeaders)
        RedfishSession.auth = (username, password)
        
        response= RedfishSession.get(bios_url,headers={"X-Auth-Token":X_Auth_Token},verify=False)
        print("Network status:",response.status_code)
        logging.debug("Get status:"+str(response.status_code))
        
        BIOS_Settings = response.json()
        BiosHeaders = response.headers
        
        #获取要修改的BIOS变量
        item_variable = MyConfig("unit_info.ini").get("item_variable",'item')
        modify_variable_value = MyConfig("unit_info.ini").get("modify_variable_value",item_variable)
        
        print(BIOS_Settings["Attributes"][item_variable])
        logging.info(BIOS_Settings["Attributes"][item_variable])
        
        #修改BIOS setting
        BIOS_Settings["Attributes"][item_variable] = modify_variable_value
        print(BIOS_Settings["Attributes"][item_variable])
        logging.info(BIOS_Settings["Attributes"][item_variable])
        PostUrl = bios_url+"Settings"
        print("Posturl:",PostUrl)
        logging.debug("Posturl:"+PostUrl)
        getEtag = RedfishSession.get(PostUrl,headers={"X-Auth-Token":X_Auth_Token},verify=False)
        logging.debug("Etag:"+getEtag.headers['ETag'])
        #通过Redfish修改BIOS settings
        headers = { 'X-Auth-Token': X_Auth_Token,
                    'Content-Type': 'application/json',
                    'If-Match': getEtag.headers['ETag']}
        
        payload = {
            "Attributes": {
                item_variable: modify_variable_value
            }
        }
        response = RedfishSession.patch(PostUrl, json=payload, headers=headers, auth=(username, password),verify=False)
        print(response.status_code)
        print()
        logging.debug("Patch Status:"+str(response.status_code))
        logging.info("")
        if int(response.status_code) == 200:
            #isAutoReboot = MyConfig("unit_info.ini").get("AutoReboot","isAutoReboot")
            isAutoReboot = False           #禁用重启             
            #print("isAutoReboot:",isAutoReboot)
            #logging.info("isAutoReboot: %s",isAutoReboot)
            AutoReboot(isAutoReboot)
            print() 
        else:
            print("Modify ",item_variable, " value Failed",)
            logging.info("Modify %s value Failed",item_variable)
########################################################
        i=i+1
        Passed = Passed+1
        
    else:
        print("ping fail: "f'{login_host} unreachable, trying next ip...') 
        print()
        logging.error("ping fail: "f'{login_host} unreachable, trying next ip...\n') 
        i=i+1
        Failed = Failed+1
           
else:
    #fail执行
    print("All ips have finished running!")
    print("Total number of passed units: ",Passed)
    print("Total number of failed units: ",Failed)
    print()  
    logging.info("All ips have finished running!")
    logging.info("Total number of passed units: %s",Passed)
    logging.info("Total number of failed units: %s",Failed)
    
logging.FileHandler(filename=log_file).close()
logging.shutdown()   
input('Press Enter to exit...\n')  